/*
 * Roda como uma thread do servidor, vai atender requisiçoes dos clientes e
 * retornar os arquivos / dados solicitados somente quando solicitados
 */
package p2p.raca.Server;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author p
 */
public class ServerRequestHandler extends Thread {
    
    private ServerSocket waitComSocket = null;
    private String conteudo = null;
    public static String clientName = null;
    public static String name = null;
    public long size;
    public ServerRequestHandler()
    {
       
    }
    
    public void openCom()
    { Socket connection = null;
        try {   
            
         waitComSocket = new ServerSocket(5050);  
         //wait until a client attempts to connect  
         connection = waitComSocket.accept();

         
         clientName = connection.getInetAddress().getHostName();
         //get an InputStream from the socket  
         DataInputStream fromClient = new DataInputStream(connection.getInputStream());
         DataOutputStream toClient = new DataOutputStream(connection.getOutputStream());
         
         byte buffer[] = new byte[1024];  
         fromClient.read(buffer); 
         conteudo = new String(buffer).trim();

            
         
         if (conteudo.contains("updateFiles"))
             conteudo = "updateFiles";
             
         if (conteudo.equals("getLista"))
         {  File myFile = new File("Lista.txt");
             toClient.write((int)myFile.length());
             toClient.flush();
                     }
         else if (conteudo.equals("getListaFile"))
         {
             File myFile = new File("Lista.txt");
             toClient.write((int)myFile.length());
             toClient.flush();
            
         }else if (conteudo.substring(0,6).equals("getPFI"))
         {
             File myFile = new File("shared/"+conteudo.substring(6,conteudo.length()) + ".pfi");
             
             toClient.write((int)myFile.length());
             toClient.flush();
         }else if (conteudo.equals("updateFiles"))
         {
             size = -1;
            while (size == -1) 
             size = fromClient.read();
                        
         }
         connection.close();
         waitComSocket.close();
      } catch (Exception e) {  
            try {
                connection.close();
            } catch (IOException ex) {
                        }
            try {
                waitComSocket.close();
            } catch (IOException ex) {
            }
      } 
 
    }
    

    @Override
    public void run()
    {
        while (true)
        {
            openCom();
            
            if (conteudo.equals("getLista"))
            {
                
                ServerRequestHandler.name = "Lista.txt";
                ServerFileSender SFS = new ServerFileSender();
                 SFS.start();
                }else if (conteudo.equals("getListaFile"))
            {
                

                    ServerRequestHandler.name = "ListaFile.txt";
                    ServerFileSender SFS = new ServerFileSender();
                    SFS.start();
                }else if (conteudo.substring(0,6).equals("getPFI"))
            {
                
                    Serv.fileList.updateFileList();
                    ServerRequestHandler.name = "shared/"+conteudo.substring(6,conteudo.length()) + ".pfi";
                    File file = new File(name);
                    
                    ServerFileSender SFS = new ServerFileSender();
                    SFS.start();
                }
            else if (conteudo.equals("updateFiles"))
            {
                try {
                         recieveFile("temp.txt");
                         File file = new File ("temp.txt");
                         BufferedReader in = new BufferedReader(new FileReader(file));
                        while (in.ready())
                        {
                            String nome = in.readLine();
                            int tam = Integer.parseInt(in.readLine());
                            PeerFileInformation PFI = new PeerFileInformation(nome, tam);
                            if (!PFI.searchPFIfor(clientName))
                                PFI.addHost(clientName);
                            PFI.savePFI(nome);
                        }
                        file.deleteOnExit();

                }catch (java.net.UnknownHostException ex) {
                    } catch (IOException ex) {
                }
              
            
            }
        }
    }
    private void recieveFile(String name) throws java.net.UnknownHostException, IOException
    {
        Socket sock = new Socket();
        while (!sock.isBound())
        {
           
            try
            {
                sock = new Socket(clientName, 5055);
            }catch (Exception e)
            {
                
            }
        }
       // clientName = sock.getInetAddress().getHostName();
        byte[] buff = new byte[1024];
        int bytesRead=0;
        InputStream is = sock.getInputStream();
        OutputStream os = sock.getOutputStream();
        File myFile = new File(name);
        if (myFile.exists())
            myFile.delete();
        myFile.createNewFile();
        
        FileOutputStream fos = new FileOutputStream(myFile);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        
        int offset=0;
        long start = System.nanoTime();
        while (offset < size)
        {
            
                bytesRead = is.read(buff, offset, 1024);
                bos.write(buff, 0, bytesRead);
                bos.flush();
                offset =+ bytesRead+1;
                 
        }

          long elapsedTime = System.nanoTime() - start;
          System.out.println("Tempo gasto para receber o arquivo: "+ myFile.getName()+ " foi: " + elapsedTime);
        bos.close();
        sock.close();
    }
}
